﻿//------------------------------------------------------------------------------
// <copyright file="ModelingAddInOptions.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using EnvDTE;

namespace ModelingAddIns
{
	/// <summary>
	/// Abstract base class for 
	/// </summary>
	[ComVisible(true), CLSCompliant(false)]
	public abstract partial class ModelingAddInOptions : UserControl, IDTToolsOptionsPage
	{
		#region Constructor, private data

		[DebuggerStepThrough]
		protected ModelingAddInOptions()
		{
			InitializeComponent();
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ModelingAddIn AddIn
		{
			[DebuggerStepThrough]
			get { return ModelingAddIn.GetInstance(this.GetType().Assembly); }
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private IMetaFeatureService Store
		{
			[DebuggerStepThrough]
			get
			{
				ModelingAddIn addin = ModelingAddIn.GetInstance(this.GetType().Assembly);
				return addin != null ? addin.Store : null;
			}
		}

		#endregion

		#region IDTToolsOptionsPage Members

		[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate")]
		public void GetProperties(ref object PropertiesObject)
		{
		}

		public void OnAfterCreated(DTE DTEObject)
		{
			Initialize();
		}

		public void OnCancel()
		{
		}

		public void OnHelp()
		{
		}

		public void OnOK()
		{
			if (treeView1.Visible)
			{
				if (UpdateFeatures(treeView1.Nodes[0], true))
				{
					// there were changes - reload the addin
					AddIn.Reload();
				}
			}
		}

		#endregion

		#region Feature tree methods

		private void Initialize()
		{
			if (this.Store == null)
			{
				label2.Visible = true;
				treeView1.Visible = false;
			}
			else
			{
				label2.Visible = false;
				treeView1.Visible = true;

				treeView1.Nodes.Clear();
				AddFeatures(null, Store.FindMetaFeature(typeof(GlobalContext)));
				treeView1.ExpandAll();
				treeView1.Nodes[0].EnsureVisible();
			}
            this.Dock = DockStyle.Fill;
		}

		private void AddFeatures(TreeNode parentNode, MetaFeature metaFeature)
		{
			TreeNode treeNode = new TreeNode();
			string text = metaFeature.Name.Replace("...", "");
			text = text.Replace("&&", "_~~_").Replace("&", "").Replace("_~~_", "&");
			treeNode.Text = text;
			treeNode.Checked = metaFeature.Enabled;
			treeNode.Tag = metaFeature;
			if (parentNode == null)
				treeView1.Nodes.Add(treeNode);
			else
				parentNode.Nodes.Add(treeNode);
			foreach (MetaFeature child in Store.GetRolePlayers(metaFeature, MetaRelationshipKind.Child))
				AddFeatures(treeNode, child);
		}

		private bool UpdateFeatures(TreeNode node, bool parentEnabled)
		{
			MetaFeature metaFeature = node.Tag as MetaFeature;
			bool result = false;
			if (metaFeature != null && metaFeature.FeatureType != typeof(GlobalContext))
			{
				bool newValue = parentEnabled & node.Checked;
				if (metaFeature.Enabled != newValue)
				{
					metaFeature.Enabled = newValue;
					result = true;
				}
			}
			foreach (TreeNode childNode in node.Nodes)
			{
				result |= UpdateFeatures(childNode, metaFeature.Enabled);
			}
			return result;
		}

		private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
		{
			MetaFeature mf = e.Node.Tag as MetaFeature;
			if (mf == null)
				descriptionLabel.Text = string.Empty;
			else
				descriptionLabel.Text = mf.Description;
		}

		private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
		{
			CheckChildren(e.Node, e.Node.Checked);
		}

		private void CheckChildren(TreeNode node, bool isChecked)
		{
			foreach (TreeNode child in node.Nodes)
			{
				child.Checked = isChecked;
				CheckChildren(child, isChecked);
			}
		}

		#endregion
	}
}
